package org.desktop.web.client.custom.widget.grid.user;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.desktop.web.client.custom.widget.grid.user.model.ModUserAssociationToProjectCheckBoxSelectionModel;
import org.desktop.web.client.user.UserService;
import org.desktop.web.client.user.UserServiceAsync;
import org.desktop.web.client.util.Util;
import org.desktop.web.shared.domain.UserAutoBeanFactory;
import org.desktop.web.shared.domain.UserRecordResult;
import org.desktop.web.shared.domain.entities.Project;
import org.desktop.web.shared.domain.entities.User;
import org.desktop.web.shared.util.WebService;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.editor.client.Editor.Path;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;
import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.Style.SelectionMode;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.client.loader.RpcProxy;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.PropertyAccess;
import com.sencha.gxt.data.shared.loader.FilterPagingLoadConfig;
import com.sencha.gxt.data.shared.loader.FilterPagingLoadConfigBean;
import com.sencha.gxt.data.shared.loader.JsonReader;
import com.sencha.gxt.data.shared.loader.ListLoadResult;
import com.sencha.gxt.data.shared.loader.ListLoadResultBean;
import com.sencha.gxt.data.shared.loader.LoadResultListStoreBinding;
import com.sencha.gxt.data.shared.loader.PagingLoadResult;
import com.sencha.gxt.data.shared.loader.PagingLoader;
import com.sencha.gxt.state.client.GridFilterStateHandler;
import com.sencha.gxt.widget.core.client.event.ActivateEvent;
import com.sencha.gxt.widget.core.client.event.ActivateEvent.ActivateHandler;
import com.sencha.gxt.widget.core.client.event.UpdateEvent;
import com.sencha.gxt.widget.core.client.event.UpdateEvent.UpdateHandler;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.grid.filters.Filter;
import com.sencha.gxt.widget.core.client.grid.filters.GridFilters;
import com.sencha.gxt.widget.core.client.grid.filters.StringFilter;
import com.sencha.gxt.widget.core.client.info.Info;

/**
 * Griglia utilizzata per aggiungere/rimuovere utenti ad un progetto. Visualizza
 * gli uten
 * 
 * @author edoardo
 *
 */
public class ModUserAssociationToProjectGrid implements IsWidget {

	private ModUserAssociationToProjectCheckBoxSelectionModel checkBoxSelectionModel;
	
	private Grid<User> grid;

	public interface UserProperties extends PropertyAccess<User> {
		@Path("id")
		ModelKeyProvider<User> key();

		ValueProvider<User, String> login();

		ValueProvider<User, String> customerDesc();

		ValueProvider<User, String> descRole();

		// ValueProvider<User, Boolean> selected();

	}

	// public interface User {
	// int getId();
	//
	// String getLogin();
	//
	// String getDescCustomer();
	//
	// String getDescRole();
	//
	// // boolean isSelected();
	// }

	

	

	public class UserDataRecordJsonReader extends
			JsonReader<ListLoadResult<User>, UserRecordResult> {
		public UserDataRecordJsonReader(AutoBeanFactory factory,
				Class<UserRecordResult> rootBeanType) {
			super(factory, rootBeanType);
		}

		@Override
		protected ListLoadResult<User> createReturnData(Object loadConfig,
				UserRecordResult incomingData) {
			return new ListLoadResultBean<User>(incomingData.getRecords());
		}
	}

	private Project project;

	public ModUserAssociationToProjectGrid(Project project) {
		// TODO Auto-generated constructor stub
		this.project = project;
	}

	@Override
	public Widget asWidget() {
		final UserServiceAsync userService = GWT.create(UserService.class);
		UserAutoBeanFactory factory = GWT
				.create(UserAutoBeanFactory.class);
//		UserDataRecordJsonReader reader = new UserDataRecordJsonReader(
//				factory, UserRecordResult.class);

		UserProperties properties = GWT.create(UserProperties.class);

		String path = new StringBuilder(
				com.google.gwt.core.client.GWT.getModuleBaseURL())
				.append("exec?service=")
				.append(WebService.GET_USERS_BY_PROJECT).toString();
		// RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, path);
		// rb.setHeader("token", Cookies.getCookie("token"));

		// TODO
		// sostituire con PagingLoadConfig e PagingLoadResult
		RpcProxy<FilterPagingLoadConfig, PagingLoadResult<User>> proxy = new RpcProxy<FilterPagingLoadConfig, PagingLoadResult<User>>() {
			@Override
			public void load(FilterPagingLoadConfig loadConfig,
					AsyncCallback<PagingLoadResult<User>> callback) {
				
				userService.getUsers(Util.getHeaders(),loadConfig,callback);
			}
		};
		
		final PagingLoader<FilterPagingLoadConfig, PagingLoadResult<User>> remoteLoader = new PagingLoader<FilterPagingLoadConfig, PagingLoadResult<User>>(
				proxy){

					@Override
					protected FilterPagingLoadConfig newLoadConfig() {
						// TODO Auto-generated method stub
						return new FilterPagingLoadConfigBean();
					}
			
		};
		

		final ListStore<User> store = new ListStore<User>(
				properties.key());
		remoteLoader.setRemoteSort(true);
		remoteLoader.addLoadHandler(new LoadResultListStoreBinding<FilterPagingLoadConfig, User, PagingLoadResult<User>>(store));

		ColumnConfig<User, String> ccLogin = new ColumnConfig<>(
				properties.login(), 150, "Login");
		ColumnConfig<User, String> ccCustomer = new ColumnConfig<>(
				properties.customerDesc(), 150, "Customer");
		ColumnConfig<User, String> ccRole = new ColumnConfig<>(
				properties.descRole(), 150, "Role");
		// ColumnConfig<User, Boolean> ccSelected = new
		// ColumnConfig<>(properties.selected(), 150, "");

		IdentityValueProvider<User> identity = new IdentityValueProvider<User>();
		checkBoxSelectionModel = new ModUserAssociationToProjectCheckBoxSelectionModel(
				identity);
		checkBoxSelectionModel.setSelectionMode(SelectionMode.MULTI);
		List<ColumnConfig<User, ?>> l = new ArrayList<ColumnConfig<User, ?>>();
		l.add(checkBoxSelectionModel.getColumn());
		l.add(ccLogin);
		l.add(ccCustomer);
		l.add(ccRole);
		ColumnModel<User> cm = new ColumnModel<User>(l);

		grid = new Grid<User>(store, cm);
		grid.setSelectionModel(checkBoxSelectionModel);
		grid.getView().setForceFit(true);
		grid.setLoader(remoteLoader);
		grid.setLoadMask(true);
		grid.setBorders(true);
		remoteLoader.load();

		StringFilter<User> loginFilter = new StringFilter<>(
				properties.login());

		loginFilter
				.addActivateHandler(new ActivateHandler<Filter<User, ?>>() {

					@Override
					public void onActivate(
							ActivateEvent<Filter<User, ?>> event) {
						// TODO Auto-generated method stub
						Info.display("", "onActivate - "
								+ event.getItem().getValue());

						remoteLoader.load();

					}
				});
		loginFilter.addUpdateHandler(new UpdateHandler() {

			@Override
			public void onUpdate(UpdateEvent event) {
				Info.display("", "onUpdate");
				remoteLoader.load();

			}
		});
		StringFilter<User> customerFilter = new StringFilter<>(
				properties.customerDesc());
		StringFilter<User> roleFilter = new StringFilter<>(
				properties.descRole());

		GridFilters<User> filters = new GridFilters<User>();
		filters.initPlugin(grid);
		filters.setLocal(true);
		filters.addFilter(loginFilter);
		filters.addFilter(roleFilter);
		filters.addFilter(customerFilter);

		GridFilterStateHandler<User> handler = new GridFilterStateHandler<User>(
				grid, filters);
		handler.loadState();
		// TODO Auto-generated method stub
		return grid;
	}

	public ModUserAssociationToProjectCheckBoxSelectionModel getCheckBoxSelectionModel() {
		return checkBoxSelectionModel;
	}

	public Map<Integer, User> getSelected() {
		return checkBoxSelectionModel.getSelected();
	}

	public Map<Integer, User> getUnselected() {
		return checkBoxSelectionModel.getUnselected();
	}

	public Grid<User> getGrid() {
		return grid;
	}

}
